using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Configuration;
using System.Globalization;
using System.Resources;
using System.Diagnostics;
using System.Net;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;


namespace Storm.CS.Lib.Soap
{

    public class StormDefaultSoap
    {
        private string _soapAction;
        public string SoapAction
        {
            get { return _soapAction; }
        }
        private string _methodName;

        public string MethodName
        {
            get { return _methodName; }
        }
        private string _soapMsg;

        public string SoapMsg
        {
            get { return _soapMsg; }
        }
        private string _contentType;

        public string ContentType
        {
            get { return _contentType; }
        }

        public StormDefaultSoap(string methodName, string fromDefWsdlHelper)
        {
            this._methodName = methodName;
            this.LoadFrom(fromDefWsdlHelper);
        }

        private void LoadFrom(string fromDefWsdlHelp)
        {
            /*  SAMPLE OUTPUT
            POST /fsws/FinanceSystemWs.asmx HTTP/1.1
            Host: scs-vpc-websvc
            Content-Type: text/xml; charset=utf-8
            Content-Length: length
            SOAPAction: "http://www.blackwellpublishing.com/financialsystem/GetBooks"
        
            <?xml version="1.0" encoding="utf-8"?>
              <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                <soap:Body>
                    <GetBooks xmlns="http://www.blackwellpublishing.com/financialsystem/" />
                </soap:Body>

             * 
             * 
             * 
             */

            if (String.IsNullOrEmpty(fromDefWsdlHelp))
                throw new ArgumentNullException("fromDefWsdlHelp", "web service response was null or empty");

            int xmlStart = fromDefWsdlHelp.IndexOf("<?xml");

            if (xmlStart <= 0)
                throw new Exception(String.Format("web service response was invalid. Response is \n\n{0} ", fromDefWsdlHelp ));
                

            string fragment = fromDefWsdlHelp.Substring(0, xmlStart);

            this.LoadContentType(fragment);
            this.LoadSoapAction(fragment);
            this.LoadSoapMsg(fromDefWsdlHelp.Replace(fragment, ""));

        }

        private void LoadSoapMsg(string fragment)
        {
            this._soapMsg = fragment;
        }

        private void LoadSoapAction(string fragment)
        {
            string soapAct = "SOAPAction:";

            fragment = fragment.Replace("\r\n", " ");  //make it one line.
            this._soapAction = Regex.Match(fragment, @"SOAPAction:\s\S+\s+").ToString().Replace(soapAct, "").Trim();
        }

        private void LoadContentType(string fragment)
        {
            fragment = fragment.Replace("\r\n", " ");  //make it one line.
            this._contentType = Regex.Match(fragment, @"Content-Type:\s\S+\s+\S+").ToString().Replace("Content-Type:", "").Trim();
        }

    }


    public class StormSoapMessages
    {
        private Dictionary<string, StormDefaultSoap> _dictOps = new Dictionary<string, StormDefaultSoap>();
        DefaultWsdlHelpGenerator _currentdefGenOfMethod = null;
        private ServiceDescriptionCollection _descs;

        public Dictionary<string, StormDefaultSoap> DefaultSoapMessages
        {
            get { return this._dictOps; }
        }


        public StormSoapMessages(ServiceDescriptionCollection descs)
        {
            _descs = descs;

        }

        public StormDefaultSoap GetDefaultSoapMessage(string operationName, bool useSoap12)
        {
            StormDefaultSoap sd = null;
            try
            {
                
                if (this._currentdefGenOfMethod == null)
                {
                    this._currentdefGenOfMethod = new DefaultWsdlHelpGenerator();
                    this._currentdefGenOfMethod.Load(this._descs);
                }

                string soap = _currentdefGenOfMethod.GetSoapOperationInput(operationName, useSoap12);
                sd = new StormDefaultSoap(operationName, soap);
                if (!this.DefaultSoapMessages.ContainsKey(operationName))
                    this.DefaultSoapMessages.Add(operationName, sd);

            }
            catch { } 
            return sd;
        }

        public Dictionary<string, StormDefaultSoap> GetDefaultSoapMessages(bool useSoap12)
        {
            List<StormDefaultSoap> defList = new List<StormDefaultSoap>();

            this._currentdefGenOfMethod = new DefaultWsdlHelpGenerator();
            this._currentdefGenOfMethod.Load(this._descs);
            List<string> methods = _currentdefGenOfMethod.MethodList;

            foreach (string methodName in methods)
            {
                if (!this.DefaultSoapMessages.ContainsKey(methodName))
                {
                    this._currentdefGenOfMethod = null;
                    this.GetDefaultSoapMessage(methodName, useSoap12);
                }
            }

            //if (this.DefaultSoapMessages.Count <= 0)
            //    throw new Exception("Unable to generate default soap Messages");



            return this.DefaultSoapMessages;

        }


        //
        //  This code was lifted from the DefaultWsdlHelpGenerator.aspx
        //  found in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG. That aspx file is used
        //  to display the default web service page when a web service URL is opened from the browser.

        private class DefaultWsdlHelpGenerator
        {

            // set this to true if you want to see a POST test form instead of a GET test form
            bool _showPost = true;

            // set this to true if you want to see the raw XML as outputted from the XmlWriter (useful for debugging)
            bool _dontFilterXml = false;

            // set this higher or lower to adjust the depth into your object graph of the sample messages
            int _maxObjectGraphDepth = 4;

            // set this higher or lower to adjust the number of array items in sample messages
            int _maxArraySize = 1;

            // set this to true to see debug output in sample messages
            bool _debug = false;

            string _soapNs = "http://schemas.xmlsoap.org/soap/envelope/";
            string _soapEncNs = "http://schemas.xmlsoap.org/soap/encoding/";
            string _soapPrefix = "soap";

            string _soap12Ns = "http://www.w3.org/2003/05/soap-envelope";
            string _soap12EncNs = "http://www.w3.org/2003/05/soap-encoding";
            string _soap12Prefix = "soap12";
            string _rpcNs = "http://www.w3.org/2003/05/soap-rpc";
            int _objectId = 0;

            string _msTypesNs = "http://microsoft.com/wsdl/types/";
            string _wsdlNs = "http://schemas.xmlsoap.org/wsdl/";

            string _urType = "anyType";

            ServiceDescriptionCollection _serviceDescriptions;

            XmlSchemas _schemas;
            string _operationName;
            OperationBinding _soapOperationBinding;
            Operation _soapOperation;
            OperationBinding _soap12OperationBinding;
            Operation _soap12Operation;
            OperationBinding _httpGetOperationBinding;
            Operation _httpGetOperation;
            OperationBinding _httpPostOperationBinding;
            Operation _httpPostOperation;
            StringWriter _writer;
            MemoryStream _xmlSrc;
            XmlTextWriter _xmlWriter;
            Uri _getUrl, _postUrl;
            Queue _referencedTypes;
            int _hrefID;
            bool _operationExists = false;
            BasicProfileViolationCollection _warnings = new BasicProfileViolationCollection();

            int _nextPrefix = 1;
            static readonly char[] hexTable = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            bool _requestIsLocal = false;



            List<string> _methodList = new List<string>();

            public List<string> MethodList
            {
                get { return this._methodList; }
            }


            public string OperationName
            {
                get { return XmlConvert.DecodeName(_operationName); }
            }

            public string ServiceName
            {
                get { return XmlConvert.DecodeName(_serviceDescriptions[0].Services[0].Name); }
            }

            public string ServiceNamespace
            {
                get { return _serviceDescriptions[0].TargetNamespace; }
            }

            public BasicProfileViolationCollection Warnings
            {
                get
                {
                    return _warnings;
                }
            }
            public string ServiceDocumentation
            {
                get { return _serviceDescriptions[0].Services[0].Documentation; }
            }

            //string FileName {
            //    get { 
            //        return Path.GetFileName(Request.Path);
            //    }
            //}

            //string EscapedFileName {
            //    get { 
            //        return HttpUtility.UrlEncode(FileName, Encoding.UTF8);
            //    }
            //}

            bool ShowingMethodList
            {
                get { return _operationName == null; }
            }

            public bool OperationExists
            {
                get { return _operationExists; }
            }


            // encodes a Unicode string into utf-8 bytes then copies each byte into a new Unicode string,
            // escaping bytes > 0x7f, per the URI escaping rules
            static string UTF8EscapeString(string source)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(source);
                StringBuilder sb = new StringBuilder(bytes.Length); // start out with enough room to hold each byte as a char
                for (int i = 0; i < bytes.Length; i++)
                {
                    byte b = bytes[i];
                    if (b > 0x7f)
                    {
                        sb.Append('%');
                        sb.Append(hexTable[(b >> 4) & 0x0f]);
                        sb.Append(hexTable[(b) & 0x0f]);
                    }
                    else
                        sb.Append((char)b);
                }
                return sb.ToString();
            }

            string EscapeParam(string param)
            {
                return param;
                // return HttpUtility.UrlEncode(param, Request.ContentEncoding);
            }

            public string GetSoapOperationInput(string opName, bool soap12)
            {



                _operationName = opName;
                OperationBinding opBinding = soap12 ? Soap12OperationBinding : SoapOperationBinding;
                if (opBinding == null) return "";
                WriteBegin();

                Port port = FindPort(opBinding.Binding);
                SoapAddressBinding soapAddress = (SoapAddressBinding)port.Extensions.Find(typeof(SoapAddressBinding));

                string action = UTF8EscapeString(((SoapOperationBinding)opBinding.Extensions.Find(typeof(SoapOperationBinding))).SoapAction);

                //Uri uri = new Uri(soapAddress.Location, false);
                Uri uri = new Uri(soapAddress.Location);

                Write("POST ");
                Write(uri.AbsolutePath);
                Write(" HTTP/1.1");
                WriteLine();

                Write("Host: ");
                Write(uri.Host);
                WriteLine();

                if (soap12)
                {
                    Write("Content-Type: application/soap+xml; charset=utf-8");
                }
                else
                {
                    Write("Content-Type: text/xml; charset=utf-8");
                }
                WriteLine();

                Write("Content-Length: ");
                WriteValue("length");
                WriteLine();

                if (!soap12)
                {
                    Write("SOAPAction: \"");
                    Write(action);
                    Write("\"");
                    WriteLine();
                }

                WriteLine();

                Operation op = soap12 ? Soap12Operation : SoapOperation;
                WriteSoapMessage(opBinding.Input, _serviceDescriptions.GetMessage(op.Messages.Input.Message), soap12);
                return WriteEnd().Replace("&gt;", ">").Replace("&lt;", "<").Replace("&amp;", "&").Replace("&apos;", "'").Replace("&quot;", "\"");
            }

            string GetSoapOperationOutput(bool soap12)
            {
                OperationBinding opBinding = soap12 ? Soap12OperationBinding : SoapOperationBinding;
                if (opBinding == null) return "";
                WriteBegin();
                if (opBinding.Output == null)
                {
                    Write("HTTP/1.1 202 Accepted");
                    WriteLine();
                }
                else
                {
                    Write("HTTP/1.1 200 OK");
                    WriteLine();
                    if (soap12)
                    {
                        Write("Content-Type: application/soap+xml; charset=utf-8");
                    }
                    else
                    {
                        Write("Content-Type: text/xml; charset=utf-8");
                    }
                    WriteLine();
                    Write("Content-Length: ");
                    WriteValue("length");
                    WriteLine();
                    WriteLine();

                    Operation op = soap12 ? Soap12Operation : SoapOperation;
                    WriteSoapMessage(opBinding.Output, _serviceDescriptions.GetMessage(op.Messages.Output.Message), soap12);
                }
                return WriteEnd();
            }

            OperationBinding SoapOperationBinding
            {
                get
                {
                    if (_soapOperationBinding == null)
                        _soapOperationBinding = FindBinding(typeof(SoapBinding));

                    return _soapOperationBinding;
                }
            }

            Operation SoapOperation
            {
                get
                {
                    if (_soapOperation == null)
                        _soapOperation = FindOperation(SoapOperationBinding);
                    return _soapOperation;
                }
            }

            bool ShowingSoap
            {
                get
                {
                    return SoapOperationBinding != null;
                }
            }

            OperationBinding Soap12OperationBinding
            {
                get
                {
                    if (_soap12OperationBinding == null)
                        _soap12OperationBinding = FindBinding(typeof(Soap12Binding));
                    return _soap12OperationBinding;
                }
            }

            Operation Soap12Operation
            {
                get
                {
                    if (_soap12Operation == null)
                        _soap12Operation = FindOperation(Soap12OperationBinding);
                    return _soap12Operation;
                }
            }

            bool ShowingSoap12
            {
                get
                {
                    return Soap12OperationBinding != null;
                }
            }

            private static string GetEncodedNamespace(string ns)
            {
                if (ns.EndsWith("/"))
                    return ns + "encodedTypes";
                else return ns + "/encodedTypes";
            }

            void WriteSoapMessage(MessageBinding messageBinding, Message message, bool soap12)
            {
                _objectId = 0;
                SoapOperationBinding soapBinding;
                SoapBodyBinding soapBodyBinding;

                string envelopeNs;
                string envelopeEncNs;
                string envelopePrefix;

                if (soap12)
                {
                    envelopeNs = _soap12Ns;
                    envelopeEncNs = _soap12EncNs;
                    envelopePrefix = _soap12Prefix;
                    soapBinding = (SoapOperationBinding)Soap12OperationBinding.Extensions.Find(typeof(Soap12OperationBinding));
                    soapBodyBinding = (SoapBodyBinding)messageBinding.Extensions.Find(typeof(Soap12BodyBinding));
                }
                else
                {
                    envelopeNs = _soapNs;
                    envelopeEncNs = _soapEncNs;
                    envelopePrefix = _soapPrefix;
                    soapBinding = (SoapOperationBinding)SoapOperationBinding.Extensions.Find(typeof(SoapOperationBinding));
                    soapBodyBinding = (SoapBodyBinding)messageBinding.Extensions.Find(typeof(SoapBodyBinding));
                }
                bool rpc = soapBinding != null && soapBinding.Style == SoapBindingStyle.Rpc;
                bool encoded = soapBodyBinding.Use == SoapBindingUse.Encoded;

                _xmlWriter.WriteStartDocument();
                _xmlWriter.WriteStartElement(envelopePrefix, "Envelope", envelopeNs);
                DefineNamespace("xsi", XmlSchema.InstanceNamespace);
                DefineNamespace("xsd", XmlSchema.Namespace);
                if (encoded)
                {
                    DefineNamespace("soapenc", envelopeEncNs);
                    string targetNamespace = message.ServiceDescription.TargetNamespace;
                    DefineNamespace("tns", targetNamespace);
                    DefineNamespace("types", GetEncodedNamespace(targetNamespace));
                    if (soap12)
                    {
                        DefineNamespace("rpc", _rpcNs);
                    }
                }

                SoapHeaderBinding[] headers = (SoapHeaderBinding[])messageBinding.Extensions.FindAll(typeof(SoapHeaderBinding));
                if (headers.Length > 0)
                {
                    _xmlWriter.WriteStartElement("Header", envelopeNs);
                    foreach (SoapHeaderBinding header in headers)
                    {
                        Message headerMessage = _serviceDescriptions.GetMessage(header.Message);
                        if (headerMessage != null)
                        {
                            MessagePart part = headerMessage.Parts[header.Part];
                            if (part != null)
                            {
                                if (encoded)
                                    WriteType(part.Type, part.Type, true, XmlSchemaForm.Qualified, -1, 0, false, soap12);
                                else
                                    WriteTopLevelElement(part.Element, 0, soap12);
                            }
                        }
                    }
                    if (encoded)
                        WriteQueuedTypes(soap12);
                    _xmlWriter.WriteEndElement();
                }

                _xmlWriter.WriteStartElement("Body", envelopeNs);
                if (soapBodyBinding.Encoding != null && soapBodyBinding.Encoding != String.Empty)
                    _xmlWriter.WriteAttributeString("encodingStyle", envelopeNs, envelopeEncNs);

                if (rpc)
                {
                    OperationBinding opBinding = soap12 ? Soap12OperationBinding : SoapOperationBinding;
                    Operation op = soap12 ? Soap12Operation : SoapOperation;
                    string messageName = opBinding.Output == messageBinding ? op.Name + "Response" : op.Name;
                    if (encoded)
                    {
                        string prefix = null;
                        if (soapBodyBinding.Namespace.Length > 0)
                        {
                            prefix = _xmlWriter.LookupPrefix(soapBodyBinding.Namespace);
                            if (prefix == null)
                                prefix = "q" + _nextPrefix++;
                        }
                        _xmlWriter.WriteStartElement(prefix, messageName, soapBodyBinding.Namespace);

                        if (soap12 && message.Parts.Count > 0 && opBinding.Output == messageBinding)
                        {
                            _xmlWriter.WriteStartElement("result", _rpcNs);
                            _xmlWriter.WriteAttributeString("xmlns", "");
                            _xmlWriter.WriteString(message.Parts[0].Name);
                            _xmlWriter.WriteEndElement();
                        }
                    }
                    else
                    {
                        _xmlWriter.WriteStartElement(messageName, soapBodyBinding.Namespace);
                    }
                }
                foreach (MessagePart part in message.Parts)
                {
                    if (encoded)
                    {
                        if (rpc)
                            WriteType(new XmlQualifiedName(part.Name, soapBodyBinding.Namespace), part.Type, encoded, XmlSchemaForm.Unqualified, 0, 0, true, soap12);
                        else
                            WriteType(part.Type, part.Type, encoded, XmlSchemaForm.Qualified, -1, 0, true, soap12); // id == -1 writes the definition without writing the id attr
                    }
                    else
                    {
                        if (rpc)
                            WriteType(new XmlQualifiedName(part.Name, null), part.Type, encoded, XmlSchemaForm.Unqualified, 0, 0, false, soap12);
                        else if (!part.Element.IsEmpty)
                            WriteTopLevelElement(part.Element, 0, soap12);
                        else
                            WriteXmlValue("xml");
                    }
                }
                if (rpc)
                {
                    _xmlWriter.WriteEndElement();
                }
                if (encoded)
                {
                    WriteQueuedTypes(soap12);
                }
                _xmlWriter.WriteEndElement();
                _xmlWriter.WriteEndElement();
            }

            string HttpGetOperationInput
            {
                get
                {
                    if (TryGetUrl == null) return "";
                    WriteBegin();

                    Write("GET ");
                    Write(TryGetUrl.AbsolutePath);

                    Write("?");
                    WriteQueryStringMessage(_serviceDescriptions.GetMessage(HttpGetOperation.Messages.Input.Message));

                    Write(" HTTP/1.1");
                    WriteLine();

                    Write("Host: ");
                    Write(TryGetUrl.Host);
                    WriteLine();

                    return WriteEnd();
                }
            }

            string HttpGetOperationOutput
            {
                get
                {
                    if (HttpGetOperationBinding == null) return "";
                    if (HttpGetOperationBinding.Output == null) return "";
                    Message message = _serviceDescriptions.GetMessage(HttpGetOperation.Messages.Output.Message);
                    WriteBegin();
                    Write("HTTP/1.1 200 OK");
                    WriteLine();
                    if (message.Parts.Count > 0)
                    {
                        Write("Content-Type: text/xml; charset=utf-8");
                        WriteLine();
                        Write("Content-Length: ");
                        WriteValue("length");
                        WriteLine();
                        WriteLine();

                        WriteHttpReturnPart(message.Parts[0].Element);
                    }

                    return WriteEnd();
                }
            }

            void WriteQueryStringMessage(Message message)
            {
                bool first = true;
                foreach (MessagePart part in message.Parts)
                {
                    int count = 1;
                    string typeName = part.Type.Name;
                    if (part.Type.Namespace != XmlSchema.Namespace && part.Type.Namespace != _msTypesNs)
                    {
                        int arrIndex = typeName.IndexOf("Array");
                        if (arrIndex >= 0)
                        {
                            typeName = CodeIdentifier.MakeCamel(typeName.Substring(0, arrIndex));
                            count = 2;
                        }
                    }
                    for (int i = 0; i < count; i++)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            Write("&amp;");
                        }
                        Write("<font class=key>");
                        Write(XmlConvert.DecodeName(part.Name));
                        Write("</font>=");

                        WriteValue(typeName);
                    }
                }
            }

            OperationBinding HttpGetOperationBinding
            {
                get
                {
                    if (_httpGetOperationBinding == null)
                        _httpGetOperationBinding = FindHttpBinding("GET");
                    return _httpGetOperationBinding;
                }
            }

            Operation HttpGetOperation
            {
                get
                {
                    if (_httpGetOperation == null)
                        _httpGetOperation = FindOperation(HttpGetOperationBinding);
                    return _httpGetOperation;
                }
            }

            bool ShowingHttpGet
            {
                get
                {
                    return HttpGetOperationBinding != null;
                }
            }

            string HttpPostOperationInput
            {
                get
                {
                    if (TryPostUrl == null) return "";
                    WriteBegin();

                    Write("POST ");
                    Write(TryPostUrl.AbsolutePath);

                    Write(" HTTP/1.1");
                    WriteLine();

                    Write("Host: ");
                    Write(TryPostUrl.Host);
                    WriteLine();

                    Write("Content-Type: application/x-www-form-urlencoded");
                    WriteLine();
                    Write("Content-Length: ");
                    WriteValue("length");
                    WriteLine();
                    WriteLine();

                    WriteQueryStringMessage(_serviceDescriptions.GetMessage(HttpPostOperation.Messages.Input.Message));

                    return WriteEnd();
                }
            }

            string HttpPostOperationOutput
            {
                get
                {
                    if (HttpPostOperationBinding == null) return "";
                    if (HttpPostOperationBinding.Output == null) return "";
                    Message message = _serviceDescriptions.GetMessage(HttpPostOperation.Messages.Output.Message);
                    WriteBegin();
                    Write("HTTP/1.1 200 OK");
                    WriteLine();
                    if (message.Parts.Count > 0)
                    {
                        Write("Content-Type: text/xml; charset=utf-8");
                        WriteLine();
                        Write("Content-Length: ");
                        WriteValue("length");
                        WriteLine();
                        WriteLine();

                        WriteHttpReturnPart(message.Parts[0].Element);
                    }

                    return WriteEnd();
                }
            }

            OperationBinding HttpPostOperationBinding
            {
                get
                {
                    if (_httpPostOperationBinding == null)
                        _httpPostOperationBinding = FindHttpBinding("POST");
                    return _httpPostOperationBinding;
                }
            }

            Operation HttpPostOperation
            {
                get
                {
                    if (_httpPostOperation == null)
                        _httpPostOperation = FindOperation(HttpPostOperationBinding);
                    return _httpPostOperation;
                }
            }

            bool ShowingHttpPost
            {
                get
                {
                    return HttpPostOperationBinding != null;
                }
            }

            MessagePart[] TryGetMessageParts
            {
                get
                {
                    if (HttpGetOperationBinding == null) return new MessagePart[0];
                    Message message = _serviceDescriptions.GetMessage(HttpGetOperation.Messages.Input.Message);
                    MessagePart[] parts = new MessagePart[message.Parts.Count];
                    message.Parts.CopyTo(parts, 0);
                    return parts;
                }
            }

            bool ShowGetTestForm
            {
                get
                {
                    if (!ShowingHttpGet) return false;
                    Message message = _serviceDescriptions.GetMessage(HttpGetOperation.Messages.Input.Message);
                    foreach (MessagePart part in message.Parts)
                    {
                        if (part.Type.Namespace != XmlSchema.Namespace && part.Type.Namespace != _msTypesNs)
                            return false;
                    }
                    return true;
                }
            }

            Uri TryGetUrl
            {
                get
                {
                    if (_getUrl == null)
                    {
                        if (HttpGetOperationBinding == null) return null;
                        Port port = FindPort(HttpGetOperationBinding.Binding);
                        if (port == null) return null;
                        HttpAddressBinding httpAddress = (HttpAddressBinding)port.Extensions.Find(typeof(HttpAddressBinding));
                        HttpOperationBinding httpOperation = (HttpOperationBinding)HttpGetOperationBinding.Extensions.Find(typeof(HttpOperationBinding));
                        if (httpAddress == null || httpOperation == null) return null;
                        _getUrl = new Uri(httpAddress.Location + httpOperation.Location);
                    }
                    return _getUrl;
                }
            }

            MessagePart[] TryPostMessageParts
            {
                get
                {
                    if (HttpPostOperationBinding == null) return new MessagePart[0];
                    Message message = _serviceDescriptions.GetMessage(HttpPostOperation.Messages.Input.Message);
                    MessagePart[] parts = new MessagePart[message.Parts.Count];
                    message.Parts.CopyTo(parts, 0);
                    return parts;
                }
            }

            bool ShowPostTestForm
            {
                get
                {
                    if (!ShowingHttpPost) return false;
                    Message message = _serviceDescriptions.GetMessage(HttpPostOperation.Messages.Input.Message);
                    foreach (MessagePart part in message.Parts)
                    {
                        if (part.Type.Namespace != XmlSchema.Namespace && part.Type.Namespace != _msTypesNs)
                            return false;
                    }
                    return true;
                }
            }

            Uri TryPostUrl
            {
                get
                {
                    if (_postUrl == null)
                    {
                        if (HttpPostOperationBinding == null) return null;
                        Port port = FindPort(HttpPostOperationBinding.Binding);
                        if (port == null) return null;
                        HttpAddressBinding httpAddress = (HttpAddressBinding)port.Extensions.Find(typeof(HttpAddressBinding));
                        HttpOperationBinding httpOperation = (HttpOperationBinding)HttpPostOperationBinding.Extensions.Find(typeof(HttpOperationBinding));
                        if (httpAddress == null || httpOperation == null) return null;
                        _postUrl = new Uri(httpAddress.Location + httpOperation.Location);
                    }
                    return _postUrl;
                }
            }

            void WriteHttpReturnPart(XmlQualifiedName elementName)
            {
                if (elementName == null || elementName.IsEmpty)
                {
                    Write("&lt;?xml version=\"1.0\"?&gt;");
                    WriteLine();
                    WriteValue("xml");
                }
                else
                {
                    _xmlWriter.WriteStartDocument();
                    WriteTopLevelElement(elementName, 0, false);
                }
            }

            XmlSchemaType GetPartType(MessagePart part)
            {
                if (part.Element != null && !part.Element.IsEmpty)
                {
                    XmlSchemaElement element = (XmlSchemaElement)_schemas.Find(part.Element, typeof(XmlSchemaElement));
                    if (element != null) return element.SchemaType;
                    return null;
                }
                else if (part.Type != null && !part.Type.IsEmpty)
                {
                    XmlSchemaType xmlSchemaType = (XmlSchemaType)_schemas.Find(part.Type, typeof(XmlSchemaSimpleType));
                    if (xmlSchemaType != null) return xmlSchemaType;
                    xmlSchemaType = (XmlSchemaType)_schemas.Find(part.Type, typeof(XmlSchemaComplexType));
                    return xmlSchemaType;
                }
                return null;
            }

            void WriteTopLevelElement(XmlQualifiedName name, int depth, bool soap12)
            {
                WriteTopLevelElement((XmlSchemaElement)_schemas.Find(name, typeof(XmlSchemaElement)), name.Namespace, depth, soap12);
            }

            void WriteTopLevelElement(XmlSchemaElement element, string ns, int depth, bool soap12)
            {
                WriteElement(element, ns, XmlSchemaForm.Qualified, false, 0, depth, false, soap12);
            }

            class QueuedType
            {
                internal XmlQualifiedName name;
                internal XmlQualifiedName typeName;
                internal XmlSchemaForm form;
                internal int id;
                internal int depth;
                internal bool writeXsiType;
            }

            void WriteQueuedTypes(bool soap12)
            {
                while (_referencedTypes.Count > 0)
                {
                    QueuedType q = (QueuedType)_referencedTypes.Dequeue();
                    WriteType(q.name, q.typeName, true, q.form, q.id, q.depth, q.writeXsiType, soap12);
                }
            }

            void AddQueuedType(XmlQualifiedName name, XmlQualifiedName type, int id, int depth, bool writeXsiType)
            {
                AddQueuedType(name, type, XmlSchemaForm.Unqualified, id, depth, writeXsiType);
            }

            void AddQueuedType(XmlQualifiedName name, XmlQualifiedName typeName, XmlSchemaForm form, int id, int depth, bool writeXsiType)
            {
                QueuedType q = new QueuedType();
                q.name = name;
                q.typeName = typeName;
                q.form = form;
                q.id = id;
                q.depth = depth;
                q.writeXsiType = writeXsiType;
                _referencedTypes.Enqueue(q);
            }

            void WriteType(XmlQualifiedName name, XmlQualifiedName typeName, int id, int depth, bool writeXsiType, bool soap12)
            {
                WriteType(name, typeName, true, XmlSchemaForm.None, id, depth, writeXsiType, soap12);
            }

            void WriteType(XmlQualifiedName name, XmlQualifiedName typeName, bool encoded, XmlSchemaForm form, int id, int depth, bool writeXsiType, bool soap12)
            {
                XmlSchemaElement element = new XmlSchemaElement();
                element.Name = name.Name;
                element.MaxOccurs = 1;
                element.Form = form;
                element.SchemaTypeName = typeName;
                WriteElement(element, name.Namespace, encoded, id, depth, writeXsiType, soap12);
            }

            void WriteElement(XmlSchemaElement element, string ns, bool encoded, int id, int depth, bool writeXsiType, bool soap12)
            {
                XmlSchemaForm form = element.Form;
                if (form == XmlSchemaForm.None)
                {
                    XmlSchema schema = _schemas[ns];
                    if (schema != null) form = schema.ElementFormDefault;
                }
                WriteElement(element, ns, form, encoded, id, depth, writeXsiType, soap12);
            }

            void WriteElement(XmlSchemaElement element, string ns, XmlSchemaForm form, bool encoded, int id, int depth, bool writeXsiType, bool soap12)
            {
                if (element == null) return;
                int count = element.MaxOccurs > 1 ? _maxArraySize : 1;

                for (int i = 0; i < count; i++)
                {
                    XmlQualifiedName elementName = (element.QualifiedName == null || element.QualifiedName.IsEmpty ? new XmlQualifiedName(element.Name, ns) : element.QualifiedName);
                    if (encoded && count > 1)
                    {
                        elementName = new XmlQualifiedName("Item", null);
                    }

                    if (IsRef(element.RefName))
                    {
                        WriteTopLevelElement(element.RefName, depth, soap12);
                        continue;
                    }

                    if (encoded)
                    {
                        string prefix = null;
                        if (form != XmlSchemaForm.Unqualified && elementName.Namespace.Length > 0)
                        {
                            prefix = _xmlWriter.LookupPrefix(elementName.Namespace);
                            if (prefix == null)
                                prefix = "q" + _nextPrefix++;
                        }

                        if (id != 0 && !soap12)
                        { // intercept array definitions
                            XmlSchemaComplexType ct = null;
                            if (IsStruct(element, out ct))
                            {
                                XmlQualifiedName typeName = element.SchemaTypeName;
                                XmlQualifiedName baseTypeName = GetBaseTypeName(ct);
                                if (baseTypeName != null && IsArray(baseTypeName))
                                    typeName = baseTypeName;
                                if (typeName != elementName)
                                {
                                    WriteType(typeName, element.SchemaTypeName, true, form, id, depth, writeXsiType, soap12);
                                    return;
                                }
                            }
                        }
                        _xmlWriter.WriteStartElement(prefix, elementName.Name, form != XmlSchemaForm.Unqualified ? elementName.Namespace : "");
                    }
                    else
                        _xmlWriter.WriteStartElement(elementName.Name, form != XmlSchemaForm.Unqualified ? elementName.Namespace : "");

                    XmlSchemaSimpleType simpleType = null;
                    XmlSchemaComplexType complexType = null;

                    if (IsPrimitive(element.SchemaTypeName))
                    {
                        if (writeXsiType) WriteTypeAttribute(element.SchemaTypeName);
                        WritePrimitive(element.SchemaTypeName);
                        //WritePrimitive("erik da pogi");
                    }
                    else if (IsEnum(element.SchemaTypeName, out simpleType))
                    {
                        if (writeXsiType) WriteTypeAttribute(element.SchemaTypeName);
                        WriteEnum(simpleType);
                    }
                    else if (IsStruct(element, out complexType))
                    {
                        if (depth >= _maxObjectGraphDepth)
                            WriteNullAttribute(encoded, soap12);
                        else if (encoded)
                        {
                            if (id != 0 || soap12)
                            {
                                // id == -1 means write the definition without writing the id
                                if (id > 0 || soap12)
                                {
                                    WriteIDAttribute(id, soap12);
                                }
                                WriteComplexType(complexType, ns, encoded, depth, writeXsiType, soap12);
                            }
                            else
                            {
                                int href = _hrefID++;
                                WriteHref(href, soap12);
                                AddQueuedType(elementName, element.SchemaTypeName, XmlSchemaForm.Qualified, href, depth, true);
                            }
                        }
                        else
                        {
                            WriteComplexType(complexType, ns, encoded, depth, false, soap12);
                        }
                    }
                    else if (IsByteArray(element, out simpleType))
                    {
                        WriteByteArray(simpleType);
                    }
                    else if (IsSchemaRef(element.RefName))
                    {
                        WriteXmlValue("schema");
                    }
                    else if (IsUrType(element.SchemaTypeName))
                    {
                        WriteTypeAttribute(new XmlQualifiedName(GetXmlValue("type"), null));
                    }
                    else
                    {
                        if (_debug)
                        {
                            WriteDebugAttribute("error", "Unknown type");
                            WriteDebugAttribute("elementName", element.QualifiedName.ToString());
                            WriteDebugAttribute("typeName", element.SchemaTypeName.ToString());
                            WriteDebugAttribute("type", element.SchemaType != null ? element.SchemaType.ToString() : "null");
                        }
                    }
                    _xmlWriter.WriteEndElement();
                    _xmlWriter.Formatting = Formatting.Indented;
                }
            }

            bool IsArray(XmlQualifiedName typeName)
            {
                return (typeName.Namespace == _soapEncNs && typeName.Name == "Array");
            }

            bool IsPrimitive(XmlQualifiedName typeName)
            {
                return (!typeName.IsEmpty &&
                        (typeName.Namespace == XmlSchema.Namespace || typeName.Namespace == _msTypesNs) &&
                        typeName.Name != _urType);
            }

            bool IsRef(XmlQualifiedName refName)
            {
                return refName != null && !refName.IsEmpty && !IsSchemaRef(refName);
            }

            bool IsSchemaRef(XmlQualifiedName refName)
            {
                return refName != null && refName.Name == "schema" && refName.Namespace == XmlSchema.Namespace;
            }

            bool IsUrType(XmlQualifiedName typeName)
            {
                return (!typeName.IsEmpty && typeName.Namespace == XmlSchema.Namespace && typeName.Name == _urType);
            }

            bool IsEnum(XmlQualifiedName typeName, out XmlSchemaSimpleType type)
            {
                XmlSchemaSimpleType simpleType = null;
                if (typeName != null && !typeName.IsEmpty)
                {
                    simpleType = (XmlSchemaSimpleType)_schemas.Find(typeName, typeof(XmlSchemaSimpleType));
                    if (simpleType != null)
                    {
                        type = simpleType;
                        return true;
                    }
                }
                type = null;
                return false;
            }

            bool IsStruct(XmlSchemaElement element, out XmlSchemaComplexType type)
            {
                XmlSchemaComplexType complexType = null;

                if (!element.SchemaTypeName.IsEmpty)
                {
                    complexType = (XmlSchemaComplexType)_schemas.Find(element.SchemaTypeName, typeof(XmlSchemaComplexType));
                    if (complexType != null)
                    {
                        type = complexType;
                        return true;
                    }
                }
                if (element.SchemaType != null && element.SchemaType is XmlSchemaComplexType)
                {
                    complexType = element.SchemaType as XmlSchemaComplexType;
                    if (complexType != null)
                    {
                        type = complexType;
                        return true;
                    }
                }
                type = null;
                return false;
            }

            bool IsByteArray(XmlSchemaElement element, out XmlSchemaSimpleType type)
            {
                if (element.SchemaTypeName.IsEmpty && element.SchemaType is XmlSchemaSimpleType)
                {
                    type = element.SchemaType as XmlSchemaSimpleType;
                    return true;
                }
                type = null;
                return false;
            }

            XmlQualifiedName ArrayItemType(string typeDef)
            {
                string ns;
                string name;

                int nsLen = typeDef.LastIndexOf(':');

                if (nsLen <= 0)
                {
                    ns = "";
                }
                else
                {
                    ns = typeDef.Substring(0, nsLen);
                }
                int nameLen = typeDef.IndexOf('[', nsLen + 1);

                if (nameLen <= nsLen)
                {
                    return new XmlQualifiedName(_urType, XmlSchema.Namespace);
                }
                name = typeDef.Substring(nsLen + 1, nameLen - nsLen - 1);

                return new XmlQualifiedName(name, ns);
            }

            void WriteByteArray(XmlSchemaSimpleType dataType)
            {
                WriteXmlValue("bytes");
            }

            void WriteEnum(XmlSchemaSimpleType dataType)
            {
                if (dataType.Content is XmlSchemaSimpleTypeList)
                { // "flags" enum -- appears inside a list
                    XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)dataType.Content;
                    dataType = list.ItemType;
                }

                bool first = true;
                if (dataType.Content is XmlSchemaSimpleTypeRestriction)
                {
                    XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)dataType.Content;
                    foreach (XmlSchemaFacet facet in restriction.Facets)
                    {
                        if (facet is XmlSchemaEnumerationFacet)
                        {
                            if (!first) _xmlWriter.WriteString(" or "); else first = false;
                            WriteXmlValue(facet.Value);
                        }
                    }
                }
            }

            void WriteArrayTypeAttribute(XmlQualifiedName type, int maxOccurs, bool soap12)
            {
                StringBuilder sb = new StringBuilder(type.Name);
                sb.Append("[");
                sb.Append(maxOccurs.ToString(CultureInfo.InvariantCulture));
                sb.Append("]");
                string prefix = DefineNamespace("q1", type.Namespace);
                if (soap12)
                {
                    XmlQualifiedName typeName = new XmlQualifiedName(type.Name, prefix);
                    _xmlWriter.WriteAttributeString("itemType", _soap12EncNs, typeName.ToString());
                    _xmlWriter.WriteAttributeString("arraySize", _soap12EncNs, maxOccurs.ToString(CultureInfo.InvariantCulture));
                }
                else
                {
                    XmlQualifiedName typeName = new XmlQualifiedName(sb.ToString(), prefix);
                    _xmlWriter.WriteAttributeString("arrayType", _soapEncNs, typeName.ToString());
                }
            }

            void WriteTypeAttribute(XmlQualifiedName type)
            {
                string prefix = DefineNamespace("s0", type.Namespace);
                _xmlWriter.WriteStartAttribute("type", XmlSchema.InstanceNamespace);
                _xmlWriter.WriteString(new XmlQualifiedName(type.Name, prefix).ToString());
                _xmlWriter.WriteEndAttribute();
            }

            void WriteNullAttribute(bool encoded, bool soap12)
            {
                if (encoded && !soap12)
                    _xmlWriter.WriteAttributeString("null", XmlSchema.InstanceNamespace, "1");
                else
                    _xmlWriter.WriteAttributeString("nil", XmlSchema.InstanceNamespace, "true");
            }

            void WriteIDAttribute(int href, bool soap12)
            {
                if (soap12)
                {
                    _xmlWriter.WriteAttributeString("id", _soap12EncNs, "id" + _objectId.ToString(CultureInfo.InvariantCulture));
                    _objectId++;
                }
                else
                {
                    _xmlWriter.WriteAttributeString("id", "id" + href.ToString(CultureInfo.InvariantCulture));
                }
            }

            void WriteHref(int href, bool soap12)
            {
                if (soap12)
                {
                    _xmlWriter.WriteAttributeString("ref", "id" + href.ToString(CultureInfo.InvariantCulture));
                }
                else
                {
                    _xmlWriter.WriteAttributeString("href", "#id" + href.ToString(CultureInfo.InvariantCulture));
                }
            }

            void WritePrimitive(XmlQualifiedName name)
            {
                if (name.Namespace == XmlSchema.Namespace && name.Name == "QName")
                {
                    DefineNamespace("q1", "http://tempuri.org/SampleNamespace");
                    WriteXmlValue("q1:QName");
                }
                else
                    WriteXmlValue(name.Name);
                    //WriteXmlValue("Erik pogi");
            }

            XmlQualifiedName GetBaseTypeName(XmlSchemaComplexType complexType)
            {
                if (complexType.ContentModel is XmlSchemaComplexContent)
                {
                    XmlSchemaComplexContent content = (XmlSchemaComplexContent)complexType.ContentModel;
                    if (content.Content is XmlSchemaComplexContentRestriction)
                    {
                        XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)content.Content;
                        return restriction.BaseTypeName;
                    }
                }
                return null;
            }

            internal class TypeItems
            {
                internal XmlSchemaObjectCollection Attributes = new XmlSchemaObjectCollection();
                internal XmlSchemaAnyAttribute AnyAttribute;
                internal XmlSchemaObjectCollection Items = new XmlSchemaObjectCollection();
                internal XmlQualifiedName baseSimpleType;
            }

            TypeItems GetTypeItems(XmlSchemaComplexType type)
            {
                TypeItems items = new TypeItems();
                if (type == null)
                    return items;

                XmlSchemaParticle particle = null;
                if (type.ContentModel != null)
                {
                    XmlSchemaContent content = type.ContentModel.Content;
                    if (content is XmlSchemaComplexContentExtension)
                    {
                        XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
                        items.Attributes = extension.Attributes;
                        items.AnyAttribute = extension.AnyAttribute;
                        particle = extension.Particle;
                    }
                    else if (content is XmlSchemaComplexContentRestriction)
                    {
                        XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)content;
                        items.Attributes = restriction.Attributes;
                        items.AnyAttribute = restriction.AnyAttribute;
                        particle = restriction.Particle;
                    }
                    else if (content is XmlSchemaSimpleContentExtension)
                    {
                        XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content;
                        items.Attributes = extension.Attributes;
                        items.AnyAttribute = extension.AnyAttribute;
                        items.baseSimpleType = extension.BaseTypeName;
                    }
                    else if (content is XmlSchemaSimpleContentRestriction)
                    {
                        XmlSchemaSimpleContentRestriction restriction = (XmlSchemaSimpleContentRestriction)content;
                        items.Attributes = restriction.Attributes;
                        items.AnyAttribute = restriction.AnyAttribute;
                        items.baseSimpleType = restriction.BaseTypeName;
                    }
                }
                else
                {
                    items.Attributes = type.Attributes;
                    items.AnyAttribute = type.AnyAttribute;
                    particle = type.Particle;
                }
                if (particle != null)
                {
                    bool sort = false;
                    if (particle is XmlSchemaGroupRef)
                    {
                        XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle;

                        XmlSchemaGroup group = (XmlSchemaGroup)_schemas.Find(refGroup.RefName, typeof(XmlSchemaGroup));
                        if (group != null)
                        {
                            items.Items = group.Particle.Items;
                            sort = group.Particle is XmlSchemaChoice || group.Particle is XmlSchemaAll;
                        }
                    }
                    else if (particle is XmlSchemaGroupBase)
                    {
                        items.Items = ((XmlSchemaGroupBase)particle).Items;
                        sort = particle is XmlSchemaChoice || particle is XmlSchemaAll;
                    }
                    if (sort)
                    {
                        ArrayList list = new ArrayList();
                        for (int i = 0; i < items.Items.Count; i++)
                        {
                            list.Add(items.Items[i]);
                        }
                        list.Sort(new XmlSchemaObjectComparer());
                        XmlSchemaObjectCollection sortedItems = new XmlSchemaObjectCollection();
                        for (int i = 0; i < list.Count; i++)
                        {
                            sortedItems.Add((XmlSchemaObject)list[i]);
                        }
                        items.Items = sortedItems;
                    }
                }
                return items;
            }

            internal class XmlSchemaObjectComparer : IComparer
            {
                public int Compare(object o1, object o2)
                {
                    return string.Compare(NameOf((XmlSchemaObject)o1), NameOf((XmlSchemaObject)o2), StringComparison.Ordinal);
                }

                internal static string NameOf(XmlSchemaObject o)
                {
                    if (o is XmlSchemaElement)
                    {
                        return ((XmlSchemaElement)o).Name;
                    }
                    else if (o is XmlSchemaAny)
                    {
                        return "*";
                    }
                    else
                    {
                        return "**";
                    }
                }
            }

            void WriteComplexType(XmlSchemaComplexType type, string ns, bool encoded, int depth, bool writeXsiType, bool soap12)
            {
                bool wroteArrayType = false;
                bool isSoapArray = false;
                TypeItems typeItems = GetTypeItems(type);
                if (encoded)
                {
                    /*
                      Check to see if the type looks like the new WSDL 1.1 array delaration:

                      <xsd:complexType name="ArrayOfInt">
                        <xsd:complexContent mixed="false">
                          <xsd:restriction base="soapenc:Array">
                            <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[]" />
                          </xsd:restriction>
                        </xsd:complexContent>
                      </xsd:complexType>

                    */

                    XmlQualifiedName itemType = null;
                    XmlQualifiedName topItemType = null;
                    string brackets = "";
                    XmlSchemaComplexType t = type;
                    XmlQualifiedName baseTypeName = GetBaseTypeName(t);
                    TypeItems arrayItems = typeItems;
                    while (t != null)
                    {
                        XmlSchemaObjectCollection attributes = arrayItems.Attributes;
                        t = null; // if we don't set t after this stop looping
                        if (baseTypeName != null && IsArray(baseTypeName) && attributes.Count > 0)
                        {
                            XmlSchemaAttribute refAttr = attributes[0] as XmlSchemaAttribute;
                            if (refAttr != null)
                            {
                                XmlQualifiedName qnameArray = refAttr.RefName;
                                if (qnameArray.Namespace == _soapEncNs && qnameArray.Name == "arrayType")
                                {
                                    isSoapArray = true;
                                    XmlAttribute typeAttribute = refAttr.UnhandledAttributes[0];
                                    if (typeAttribute.NamespaceURI == _wsdlNs && typeAttribute.LocalName == "arrayType")
                                    {
                                        itemType = ArrayItemType(typeAttribute.Value);
                                        if (topItemType == null)
                                            topItemType = itemType;
                                        else
                                            brackets += "[]";

                                        if (!IsPrimitive(itemType))
                                        {
                                            t = (XmlSchemaComplexType)_schemas.Find(itemType, typeof(XmlSchemaComplexType));
                                            arrayItems = GetTypeItems(t);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (itemType != null)
                    {
                        wroteArrayType = true;
                        if (IsUrType(itemType))
                            WriteArrayTypeAttribute(new XmlQualifiedName(GetXmlValue("type") + brackets, null), _maxArraySize, soap12);
                        else
                            WriteArrayTypeAttribute(new XmlQualifiedName(itemType.Name + brackets, itemType.Namespace), _maxArraySize, soap12);

                        for (int i = 0; i < _maxArraySize; i++)
                        {
                            WriteType(new XmlQualifiedName("Item", null), topItemType, 0, depth + 1, false, soap12);
                        }
                    }
                }

                if (writeXsiType && !wroteArrayType)
                {
                    WriteTypeAttribute(type.QualifiedName);
                }

                if (!isSoapArray)
                {
                    foreach (XmlSchemaAttribute attr in typeItems.Attributes)
                    {
                        if (attr != null && attr.Use != XmlSchemaUse.Prohibited)
                        {
                            if (attr.Form == XmlSchemaForm.Qualified && attr.QualifiedName != null)
                                _xmlWriter.WriteStartAttribute(attr.Name, attr.QualifiedName.Namespace);
                            else
                                _xmlWriter.WriteStartAttribute(attr.Name, null);

                            XmlSchemaSimpleType dataType = null;

                            // special code for the QNames
                            if (attr.SchemaTypeName.Namespace == XmlSchema.Namespace && attr.SchemaTypeName.Name == "QName")
                            {
                                WriteXmlValue("q1:QName");
                                _xmlWriter.WriteEndAttribute();
                                DefineNamespace("q1", "http://tempuri.org/SampleNamespace");
                            }
                            else
                            {
                                if (IsPrimitive(attr.SchemaTypeName))
                                    WriteXmlValue(attr.SchemaTypeName.Name);
                                else if (IsEnum(attr.SchemaTypeName, out dataType))
                                    WriteEnum(dataType);
                                _xmlWriter.WriteEndAttribute();
                            }
                        }
                    }
                }

                XmlSchemaObjectCollection items = typeItems.Items;
                foreach (object item in items)
                {
                    if (item is XmlSchemaElement)
                    {
                        WriteElement((XmlSchemaElement)item, ns, encoded, 0, depth + 1, encoded, soap12);
                    }
                    else if (item is XmlSchemaAny)
                    {
                        XmlSchemaAny any = (XmlSchemaAny)item;
                        XmlSchema schema = _schemas[any.Namespace];
                        if (schema == null)
                        {
                            WriteXmlValue("xml");
                        }
                        else
                        {
                            foreach (object schemaItem in schema.Items)
                            {
                                if (schemaItem is XmlSchemaElement)
                                {
                                    if (IsDataSetRoot((XmlSchemaElement)schemaItem))
                                        WriteXmlValue("dataset");
                                    else
                                        WriteTopLevelElement((XmlSchemaElement)schemaItem, any.Namespace, depth + 1, soap12);
                                }
                            }
                        }
                    }
                }
            }

            bool IsDataSetRoot(XmlSchemaElement element)
            {
                if (element.UnhandledAttributes == null) return false;
                foreach (XmlAttribute a in element.UnhandledAttributes)
                {
                    if (a.NamespaceURI == "urn:schemas-microsoft-com:xml-msdata" && a.LocalName == "IsDataSet")
                        return true;
                }
                return false;
            }

            void WriteBegin()
            {
                _writer = new StringWriter();
                _xmlSrc = new MemoryStream();
                _xmlWriter = new XmlTextWriter(_xmlSrc, new UTF8Encoding(false));
                _xmlWriter.Formatting = Formatting.Indented;
                _xmlWriter.Indentation = 2;
                _referencedTypes = new Queue();
                _hrefID = 1;
            }

            string WriteEnd()
            {
                _xmlWriter.Flush();
                _xmlSrc.Position = 0;
                StreamReader reader = new StreamReader(_xmlSrc, Encoding.UTF8);
                _writer.Write(HtmlEncode(reader.ReadToEnd()));
                return _writer.ToString();
            }

            string HtmlEncode(string text)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < text.Length; i++)
                {
                    char c = text[i];
                    if (c == '&')
                    {
                        string special = ReadComment(text, i);
                        if (special.Length > 0)
                        {
                            //    sb.Append(Server.HtmlDecode(special));
                            i += (special.Length + "&lt;!--".Length + "--&gt;".Length - 1);
                        }
                        else
                            sb.Append("&amp;");
                    }
                    else if (c == '<')
                        sb.Append("&lt;");
                    else if (c == '>')
                        sb.Append("&gt;");
                    else
                        sb.Append(c);
                }
                return sb.ToString();
            }

            string ReadComment(string text, int index)
            {
                if (_dontFilterXml) return String.Empty;
                if (string.Compare(text, index, "&lt;!--", 0, "&lt;!--".Length, StringComparison.Ordinal) == 0)
                {
                    int start = index + "&lt;!--".Length;
                    int end = text.IndexOf("--&gt;", start);
                    if (end < 0) return String.Empty;
                    return text.Substring(start, end - start);
                }
                return String.Empty;
            }

            void Write(string text)
            {
                _writer.Write(text);
            }

            void WriteLine()
            {
                _writer.WriteLine();
            }

            void WriteValue(string text)
            {
                //Write("<font class=value>" + text + "</font>");
                Write(text);
            }

            void WriteStartXmlValue()
            {
                _xmlWriter.WriteString("<!--<font class=value>");
            }

            void WriteEndXmlValue()
            {
                _xmlWriter.WriteString("</font>-->");
            }

            void WriteDebugAttribute(string text)
            {
                WriteDebugAttribute("debug", text);
            }

            void WriteDebugAttribute(string id, string text)
            {
                _xmlWriter.WriteAttributeString(id, text);
            }

            string GetXmlValue(string text)
            {
                //return "<!--<font class=value>" + text + "</font>-->";
                
                //HACK:  ERIK Araojo, set the correct initial values.
                string instanceVal = "";
                switch (text)
                {
                    case "guid": instanceVal = Guid.NewGuid().ToString(); break;
                    case "string": instanceVal = ""; break;
                    case "int": instanceVal = "0"; break;
                    case "integer": instanceVal = "0"; break;
                    case "nonNegativeInteger": instanceVal = "1"; break;
                    case "nonPositiveInteger": instanceVal = "-1"; break;
                    case "positiveInteger": instanceVal = "1"; break;
                    case "negativeInteger": instanceVal = "-1"; break;
                    case "double": instanceVal = "0"; break;
                    case "long": instanceVal = "10"; break;
                    case "short": instanceVal = "0"; break;
                    case "unsignedInt": instanceVal = "1"; break;
                    case "unsignedLong": instanceVal = "1"; break;
                    case "unsignedShort": instanceVal = "1"; break;

                    case "float": instanceVal = "0"; break;
                    case "decimal": instanceVal = "0.0"; break;
                    case "boolean": instanceVal = "false"; break;
                    case "byte": instanceVal = "0"; break;
                    case "date": instanceVal = "1980-05-31"; break; //My Birthday!! 
                    case "dateTime": instanceVal = "1980-05-31T13:20:00.000-05:00"; break;
                    case "time": instanceVal = "13:20:00.000-05:00"; break;
                    default: instanceVal = text; break;

                    
                }
                return instanceVal;
            }

            void WriteXmlValue(string text)
            {
                _xmlWriter.WriteString(GetXmlValue(text));
            }

            string DefineNamespace(string prefix, string ns)
            {
                if (ns == null || ns == String.Empty) return null;
                string existingPrefix = _xmlWriter.LookupPrefix(ns);
                if (existingPrefix != null && existingPrefix.Length > 0)
                    return existingPrefix;
                _xmlWriter.WriteAttributeString("xmlns", prefix, null, ns);
                return prefix;
            }

            Port FindPort(Binding binding)
            {
                foreach (ServiceDescription description in _serviceDescriptions)
                {
                    foreach (Service service in description.Services)
                    {
                        foreach (Port port in service.Ports)
                        {
                            if (port.Binding.Name == binding.Name &&
                                port.Binding.Namespace == binding.ServiceDescription.TargetNamespace)
                            {
                                return port;
                            }
                        }
                    }
                }
                return null;
            }

            OperationBinding FindBinding(Type bindingType)
            {
                OperationBinding nextBestMatch = null;
                foreach (ServiceDescription description in _serviceDescriptions)
                {
                    foreach (Binding binding in description.Bindings)
                    {
                        object ext = binding.Extensions.Find(bindingType);
                        if (ext == null) continue;
                        foreach (OperationBinding operationBinding in binding.Operations)
                        {
                            string messageName = operationBinding.Input.Name;
                            if (messageName == null || messageName.Length == 0)
                                messageName = operationBinding.Name;
                            if (messageName == _operationName)
                            {
                                if (ext.GetType() != bindingType) continue;
                                else return operationBinding;
                            }
                        }
                    }
                }
                return nextBestMatch;
            }

            OperationBinding FindHttpBinding(string verb)
            {
                foreach (ServiceDescription description in _serviceDescriptions)
                {
                    foreach (Binding binding in description.Bindings)
                    {
                        HttpBinding httpBinding = (HttpBinding)binding.Extensions.Find(typeof(HttpBinding));
                        if (httpBinding == null)
                            continue;
                        if (httpBinding.Verb != verb)
                            continue;
                        foreach (OperationBinding operationBinding in binding.Operations)
                        {
                            string messageName = operationBinding.Input.Name;
                            if (messageName == null || messageName.Length == 0)
                                messageName = operationBinding.Name;
                            if (messageName == _operationName)
                                return operationBinding;
                        }
                    }
                }
                return null;
            }

            Operation FindOperation(OperationBinding operationBinding)
            {
                PortType portType = _serviceDescriptions.GetPortType(operationBinding.Binding.Type);
                foreach (Operation operation in portType.Operations)
                {
                    if (operation.IsBoundBy(operationBinding))
                    {
                        return operation;
                    }
                }
                return null;
            }

            string GetLocalizedText(string name)
            {
                return GetLocalizedText(name, new object[0]);
            }

            string GetLocalizedText(string name, object[] args)
            {
                //    ResourceManager rm = (ResourceManager)Application["RM"];
                //string val = rm.GetString("HelpGenerator" + name);
                //if (val == null) return String.Empty;
                //return String.Format(val, args);
                return String.Format(name, args); ;
            }

            public void Load(ServiceDescriptionCollection serviceDescs)
            {
                //if (Application["RM"] == null) {
                //    lock (this.GetType()) {
                //        if (Application["RM"] == null) {
                //            Application["RM"] = new ResourceManager("System.Web.Services", typeof(System.Web.Services.WebService).Assembly);
                //        }
                //    }
                //}

                //operationName = Request.QueryString["op"];

                // Slots filled on HttpContext:
                // "wsdls"              A ServiceDescriptionCollection representing what is displayed for .asmx?wsdl
                // "schemas"            An XmlSchemas object containing schemas associated with .asmx?wsdl
                // "wsdlsWithPost"      Wsdls the same as "wsdls", plus bindings for the HttpPost protocol.
                // "schemasWithPost"    Schemas corresponding to "wsdlsWithPost".
                // The objects stored at "wsdlsWithPost" and "schemasWithPost" are available if
                // the HttpPost protocol is turned on in config.

                // Obtain WSDL contract from Http Context

                //            XmlSchemas schemasToUse;
                //serviceDescriptions = (ServiceDescriptionCollection) Context.Items["wsdlsWithPost"];
                //if (serviceDescriptions != null) {
                //    requestIsLocal = true;
                //    schemasToUse = (XmlSchemas) Context.Items["schemasWithPost"];
                //}
                //else {
                //    serviceDescriptions = (ServiceDescriptionCollection) Context.Items["wsdls"];
                //    schemasToUse = (XmlSchemas) Context.Items["schemas"];
                //}


                XmlSchemas schemas2 = new XmlSchemas();
                //foreach (XmlSchema schema in schemasToUse) {
                //    schemas.Add(schema);
                //}
                foreach (ServiceDescription description in serviceDescs)
                {
                    foreach (XmlSchema schema in description.Types.Schemas)
                    {
                        schemas2.Add(schema);
                    }
                }

                // SortedList methodsTable = new SortedList(StringComparer.Ordinal);
                _operationExists = false;

                this._serviceDescriptions = serviceDescs;
                this._schemas = schemas2;

                foreach (ServiceDescription description in serviceDescs)
                {
                    foreach (PortType portType in description.PortTypes)
                    {
                        foreach (Operation operation in portType.Operations)
                        {
                            string messageName = operation.Messages.Input.Name;
                            if (messageName == null || messageName.Length == 0)
                                messageName = operation.Name;
                            if (messageName == _operationName)
                                _operationExists = true;
                            if (messageName == null)
                                messageName = String.Empty;

                            this._methodList.Add(operation.Name);
                            //string defSoap = this.GetSoapOperationInput(operation.Name, soap12);
                            //this._dictOps.Add(operation.Name, defSoap);
                            //methodsTable[messageName] = operation;

                        }
                    }
                }


                //  bool checkClaims = ((WsiProfiles)Context.Items["conformanceWarnings"] & WsiProfiles.BasicProfile1_1) != 0;
                // if (checkClaims) {
                //      warnings = new BasicProfileViolationCollection();
                //     WebServicesInteroperability.CheckConformance(WsiProfiles.BasicProfile1_1, serviceDescriptions, warnings);
                //  }
                // MethodList.DataSource = methodsTable;
                // Databind all values within the page
                // Page.DataBind();
            }


        }
    }
}